﻿#region Copyright © 2011 Prageeth Silva <prageeth@thenewcoders.com>
/*
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the author(s) be held liable for any damages arising from
 * the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 *   1. The origin of this software must not be misrepresented; you must not
 *      claim that you wrote the original software. If you use this software
 *      in a product, an acknowledgment in the product documentation would be
 *      appreciated but is not required.
 * 
 *   2. Altered source versions must be plainly marked as such, and must not
 *      be misrepresented as being the original software.
 * 
 *   3. This notice may not be removed or altered from any source distribution.
 */
#endregion

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
using SourcePlus.Themes;
using System.Text;

namespace SourcePlus
{
    /// <summary>
    /// Global settings class acting as static.
    /// This is a wrapper class around the actual object.
    /// </summary>
    public class Settings
    {
        
        public const string FilePath = "settings.xml";

        private static SettingsObject settings { get; set; }

        public static List<SourceTheme> Themes
        {
            get { return settings.Themes; }
        }

        public static string ThemesExamplePath
        {
            get { return settings.ThemesExamplePath; }
            set { settings.ThemesExamplePath = value; }
        }

        public static bool Load()
        {
            return Load(FilePath);
        }

        public static bool Load(string file)
        {

            TextReader textReader = null;
            try
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(SettingsObject));
                textReader = new StreamReader(file);
                settings = (SettingsObject)deserializer.Deserialize(textReader);
                settings.Initialise();
                return true;
            }
            catch
            {
                // try to read default settings
                try
                {
                    XmlSerializer deserializer = new XmlSerializer(typeof(SettingsObject));
                    Stream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(Properties.Resources.default_settings));
                    textReader = new StreamReader(stream);
                    settings = (SettingsObject)deserializer.Deserialize(textReader);
                    settings.Initialise();
                    return true;
                }
                catch
                {
                    settings = new SettingsObject();
                    return false;
                }               
            }
            finally
            {
                if (textReader != null) { textReader.Close(); }
            }

        }

        public static bool Save()
        {
            return Save(FilePath);
        }

        public static bool Save(string file)
        {

            if (settings == null) { return false; }

            TextWriter textWriter = null;
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(SettingsObject));
                textWriter = new StreamWriter(file);
                serializer.Serialize(textWriter, settings);
                textWriter.Close();
                return true;
            }
            catch (Exception e)
            {
                Console.Out.Write(e.StackTrace);
                return false;
            }
            finally
            {
                if (textWriter != null) { textWriter.Close(); }
            }

        }

        #region "Inner serializable object"

        /// <summary>
        /// The object that's been serialized in real to hold settings.
        /// </summary>
        [XmlRootAttribute]
        public class SettingsObject
        {

            [XmlArray]
            [XmlArrayItem(Type = typeof(SourceTheme))]
            public List<SourceTheme> Themes { get; set; }

            [XmlElement]
            public string ThemesExamplePath { get; set; }
            
            public SettingsObject()
            {
                this.Themes = new List<SourceTheme>();
                this.ThemesExamplePath = string.Empty;
            }

            public void Initialise()
            {
                foreach (SourceTheme theme in this.Themes)
                {
                    theme.Initialise();
                }
            }

        }

        #endregion

    }

}
